package com.ericsson.epc.modules.kpi.task.epc;

import com.ericsson.common.quartz.task.ManualTask;
import com.ericsson.common.util.DateUtils;
import com.ericsson.common.util.FormulaConvert;
import com.ericsson.common.util.LogFileName;
import com.ericsson.common.util.LoggerUtils;
import com.ericsson.epc.modules.kpi.entity.Formula;
import com.ericsson.epc.modules.kpi.service.FormulaService;
import com.ericsson.epc.modules.kpi.thread.epc.KpiDataProcessEpcThread;
import com.ericsson.epc.modules.sys.entity.Dict;
import com.ericsson.epc.modules.sys.entity.EPCNetElement;
import com.ericsson.epc.modules.sys.entity.IMSNetElement;
import com.ericsson.epc.modules.sys.service.DictService;
import com.ericsson.epc.modules.sys.service.EPCNetElementService;
import com.ericsson.epc.modules.sys.service.IMSNetElementService;
import com.ericsson.epc.modules.userebm.entity.EpcDictEBM;
import com.ericsson.epc.modules.userebm.mapper.EpcDictEBMMapper;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;

/**
 * ims指标处理
 */
@Component
public class EpcKpiTask implements ManualTask {
    private Logger log = LoggerUtils.Logger(LogFileName.EpcKpiJob);

    private static final String DICT_NET_TYPE = "biz_net_type";
    private static final String DICT_KPI_PARAM = "kpi_epc_param";
    @Autowired
    private DictService dictService;
    @Autowired
    @Qualifier("formulaEpcService")
    private FormulaService formulaService;
    @Autowired
    private EPCNetElementService epcNetElementService;
    @Autowired
    private IMSNetElementService imsNetElementService;
    @Value("${epckpiDownloadDir}")
    private String epckpiDownloadDir;
    @Value("${baseDir}")
    private String baseDir;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void execute() {
       Date now = new Date();
        //删除过期数据
       deleteMongodbData(now);
       //查询NBI网元 ims nettype 4:NBI
       IMSNetElement imsNetElement=null;
       List<IMSNetElement> imsNetElements= imsNetElementService.findNetList("4");//查询NBI数据
       if(imsNetElements.size()>0){
           imsNetElement=imsNetElements.get(0);
       }
       //查询字典表中的EPC网元类型
       List<Dict> epcNetTypeList= dictService.findDictList(DICT_NET_TYPE);
        List<Dict> kpiParamList= dictService.findDictList(DICT_KPI_PARAM);
       for(Dict epcNetType: epcNetTypeList) {
           //1:MME  2:GWC(SAEGW)   3:PCRF  4:GWU
           if (epcNetType.getValue().equals("1") || epcNetType.getValue().equals("2") || epcNetType.getValue().equals("3")|| epcNetType.getValue().equals("4")) {
               List<EPCNetElement> epcNetElementList= epcNetElementService.getList(Long.parseLong(epcNetType.getValue()));
                Map<String,EPCNetElement> imsNetElementMap=new HashMap<>();
               for(EPCNetElement EPCNetElement:epcNetElementList){
                   imsNetElementMap.put(EPCNetElement.getKpiAlias(),EPCNetElement);
               }
               List<Formula> formulaList = formulaService.findFormulaList(Long.parseLong(epcNetType.getValue()));
               //存储公式的空间粒度，为解析时使用，如果xml中的空间粒度不在列表中  就不解析对应的部分Measurements
               List<String> formulaUnit=new ArrayList<>();
               Map<Long, Expression> formulaExpressions = new HashMap<>();
               for (Iterator iter = formulaList.iterator(); iter.hasNext(); ) {
                   Formula f = (Formula) iter.next();
                   log.info("=======type======= " + epcNetType.getLabel() + " =====Formula==== " + f.getFormula());
                   formulaUnit.add(f.getObjtype());
                   if(f.getFormula().contains("EPC_DICT.")){
                       f.setFormula(f.getFormula().replace("EPC_DICT.",""));
                       for(Dict dict:kpiParamList){
                           if(f.getFormula().contains(dict.getLabel())){
                               f.setFormula(f.getFormula().replace(dict.getLabel(),dict.getValue()));
                               break;
                           }
                       }
                   }
                   String formulaText = FormulaConvert.convertFormula(f.getFormula());
                   try {
                       Expression compiledExp = AviatorEvaluator.compile(formulaText);
                       formulaExpressions.put(f.getId(), compiledExp);
                   } catch (Exception e) {
                       iter.remove();
                       log.error("error====" + e.getMessage() + "====", e);
                   } finally {
                       continue;
                   }
               }
               if(epcNetType.getLabel().equals("SAEGW")){
                   epcNetType.setLabel("GWC");
               }
               String path=this.baseDir+File.separator+this.epckpiDownloadDir;
               KpiDataProcessEpcThread kpiDataProcessThread=new KpiDataProcessEpcThread(imsNetElement, formulaExpressions, epcNetType.getLabel(), formulaList, now, log,path,formulaUnit,imsNetElementMap);
               kpiDataProcessThread.run();
               // new Thread(kpiDataProcessThread).start();
           }
       }
    }


    @Autowired
    private EpcDictEBMMapper epcDictEBMMapper;

    /**
     * 删除过期数据
     * @param now
     */
    private void deleteMongodbData(Date now){
        EpcDictEBM epcDict=new EpcDictEBM();
        epcDict.setType("IMSKPIMONGODBTIME");
        epcDict= epcDictEBMMapper.selectEpcDictEBM(epcDict);
        if(null!=epcDict&&!"".equals(epcDict.getValue())) {
            String deleteTime = DateUtils.getStatisTime(Integer.parseInt(epcDict.getValue())*1440+30,now,"yyyy-MM-dd HH:mm:00");
            log.info("deleteTime-------------------------------:"+deleteTime);
            Query query = Query.query(Criteria.where("dateTime").lte(deleteTime));
            mongoTemplate.remove(query,"imskpi_mme");
            mongoTemplate.remove(query,"imskpi_gwc");
            mongoTemplate.remove(query,"imskpi_gwu");
            mongoTemplate.remove(query,"imskpi_pcrf");
        }
    }
}
